package com.oceansoft.mobile.weixin.service;

import com.oceansoft.mobile.biz.admin.entity.Merchant;
import com.oceansoft.mobile.common.base.entity.Pager;
import com.oceansoft.mobile.common.base.entity.Query;
import com.oceansoft.mobile.common.dao.ICommonDao;
import com.oceansoft.mobile.common.util.CacheBaseService;
import com.oceansoft.mobile.weixin.entity.*;
import com.oceansoft.mobile.weixin.entity.message.req.SuperMessage;
import com.oceansoft.mobile.weixin.entity.message.resp.Article;
import com.oceansoft.mobile.weixin.util.DateUtil;
import com.oceansoft.mobile.weixin.util.WX_Constants;
import com.oceansoft.mobile.weixin.util.WeixinUtil;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class WechatServiceImpl implements WechatService {
    @Resource
    private ICommonDao commonDao;

    @Override
    public String getSTAccessToken(String merid) throws Exception{
        String access_token = "";
        String cachekey = "ST_ACCESSTOKEN:"+merid;
        if (CacheBaseService.getInstance().exists(cachekey)) {
            access_token = CacheBaseService.getInstance().get(cachekey);
        } else {
            WxToken token =  WeixinUtil.loadTokenByMerid(merid);
            St_AccessToken at = WeixinUtil.getST_AccessToken(token.getSt_appid(),token.getSt_appsecret());
            access_token = at.getSt_access_token();
            CacheBaseService.getInstance().cache(cachekey,access_token, 5400);
        }
        return access_token;
    }

    @Override
    public String getJsapiTicket() {
        String jsapiTicket = "";
        //TODO 增加公众号微信号
        String access_token = getAccessToken("");
        String cachekey = "CMCX_JSAPITICKET";
        if (CacheBaseService.getInstance().exists(cachekey)) {
            jsapiTicket = CacheBaseService.getInstance().get(cachekey);
        } else {
//            jsapiTicket = WeixinUtil.getJsapiTicket(access_token);
//            CacheBaseService.getInstance().cache(cachekey, jsapiTicket, 7200l);
        }
        return jsapiTicket;
    }

    @Override
    public String getJsapiTicket2() {
        String jsapiTicket = "";
        String access_token = getAccessToken2();
            jsapiTicket = WeixinUtil.getJsapiTicket(access_token);
        return jsapiTicket;
    }

    private String getAccessToken(String wx_openid) {
        return WeixinUtil.getAccessToken(wx_openid);
    }

    private String getAccessToken2(){
        String access_token = "";
        String cachekey = "PICTUREUPLOAD_ACCESSTOKEN";
        if (CacheBaseService.getInstance().exists(cachekey)) {
            access_token = CacheBaseService.getInstance().get(cachekey);
        } else {
            WxToken at = WeixinUtil.getAccessToken(WeixinUtil.APPID, WeixinUtil.SECRET);
            access_token = at.getAccess_token();
            CacheBaseService.getInstance().cache(cachekey,access_token, 7200l);
        }
        return access_token;
    }
    public String getAccessTokenByopenId(String wx_openid) {
        return getAccessToken(wx_openid);
    }


    public String findWXOpenIdbyMerId(String mer_id) {
        return commonDao.getStringColumn("select openid from wx_token where mer_id=?", mer_id);
    }

    @Override
    public List<Map<String, Object>> findFirstMenu(String openid) {
        return commonDao.loadMapList("select * from wx_menu t where t.parentid is NULL and t.status= 1 and t.wx_openid = ?  ", openid);
    }

    @Override
    public List<Map<String, Object>> findSecondMenu(Long first_menu_id) {
        String sql = "select * from wx_menu t where t.parentid = ? and t.status = 1 ";
        return commonDao.loadMapList(sql, first_menu_id);
    }

    /**
     * 根据微信公众账号原始id查询商家
     *
     * @param weixin_openid 微信公众账号原始id
     */
    public Merchant findbyOpenid(String weixin_openid) {
        return commonDao.loadOne("SELECT t1.* from t_merchant t1 LEFT JOIN wx_token t2 on t2.mer_id=t1.sid where t2.openid=? ", Merchant.getFullMapp(),
                weixin_openid);
    }

    public boolean saveUserMsg(SuperMessage sm) {
        int rt = commonDao
                .saveOne(
                        "INSERT INTO wx_msg (ToUserName,FromUserName,CreateTime,MsgType,MsgId,Content,Location_X,Location_Y,Scale,Label,Title,Description,Url,PicUrl,MediaId,ThumbMediaId,Format) VALUES(:ToUserName,:FromUserName,:CreateTime,:MsgType,:MsgId,:Content,:Location_X,:Location_Y,:Scale,:Label,:Title,:Description,:Url,:PicUrl,:MediaId,:ThumbMediaId,:Format)",
                        sm);
        return rt > 0 ? true : false;
    }

    public boolean saveUserSub(WX_User_sub sub) {
        int rt = commonDao.saveOne(
                "INSERT INTO wx_user_sub (wx_openid,user_openid,createtime,sub_unsub) VALUES(:wx_openid,:user_openid,:createtime,:sub_unsub)", sub);
        return rt > 0 ? true : false;
    }

    public synchronized WX_User subscribeWXUser(String user_openid, String wx_openid) {
        WX_User user = commonDao.loadOne("SELECT * from wx_user where openid=?", WX_User.getMapp(), user_openid);
        if (null != user) {// 如果已经有这个用户了，说明以前关注过,这里只更新关注标识和日期
            commonDao.updateColumn2("wx_user", "openid", user_openid, "subscribe", 1, "subscribe_time", new Date().getTime());
        } else {
            // 如果是订阅号 ,则此处总为NULL,因为没有权限. 认证服务号才能正确获取用户信息
            // 如果是认证服务号,此处可以获得用户基本信息
            String access_token = WeixinUtil.getAccessToken(wx_openid);
            user = WeixinUtil.getUserInfo(access_token, user_openid);
            if (null == user) {
                user = new WX_User();
                user.setOpenid(user_openid);
                user.setSubscribe(1);
                user.setSubscribe_time(new Date().getTime());
                user.setExpires(new Date().getTime());
            }
            user.setCreate_time(new Date());
            user.setWx_openid(wx_openid);
            try {
				commonDao
				        .saveOne(
				                "INSERT INTO wx_user (subscribe,openid,nickname,sex,city,country,province,language,headimgurl,subscribe_time,wx_openid,create_time,unionid) VALUES(:subscribe,:openid,:nickname,:sex,:city,:country,:province,:language,:headimgurl,:subscribe_time,:wx_openid,:create_time,:unionid) ",
				                user);
			} catch (Exception e) {
				user.setNickname(user_openid);
				commonDao
		        .saveOne(
		                "INSERT INTO wx_user (subscribe,openid,nickname,sex,city,country,province,language,headimgurl,subscribe_time,wx_openid,create_time,unionid) VALUES(:subscribe,:openid,:nickname,:sex,:city,:country,:province,:language,:headimgurl,:subscribe_time,:wx_openid,:create_time,:unionid) ",
		                user);
			}
            //修改用户的扫码记录
            commonDao.update("update t_api_access_log  set succ='true' where openid=? and result='ewm' and  logdate=sysdate ",user_openid);
            
            
        }
        return user;
    }


    public void addWXUser(String user_openid, String wx_openid) {
        WX_User user = commonDao.loadOne("SELECT * from wx_user where openid=?", WX_User.getMapp(), user_openid);
        System.out.println("-----subscribeWXUser2-----");
        if (null == user) {// 如果已经有这个用户了，说明以前关注过,这里只更新关注标识和日期
            System.out.println("-----addUser2-----");
            // 如果是订阅号 ,则此处总为NULL,因为没有权限. 认证服务号才能正确获取用户信息
            // 如果是认证服务号,此处可以获得用户基本信息
            user = WeixinUtil.getUserInfo(getAccessTokenByopenId(wx_openid), user_openid);
            if (null == user) {
                user = new WX_User();
                user.setOpenid(user_openid);
                user.setSubscribe(1);
                user.setSubscribe_time(new Date().getTime());
                user.setExpires(new Date().getTime());
            }
            user.setCreate_time(new Date());
            user.setWx_openid(wx_openid);
            commonDao
                    .saveOne(
                            "INSERT INTO wx_user (subscribe,openid,nickname,sex,city,country,province,language,headimgurl,subscribe_time,wx_openid,create_time,unionid) VALUES(:subscribe,:openid,:nickname,:sex,:city,:country,:province,:language,:headimgurl,:subscribe_time,:wx_openid,:create_time,:unionid) ",
                            user);
        }
    }


    public WX_User getWXUser(String user_openid, String wx_openid) {
        WX_User user = commonDao.loadOne("SELECT * from wx_user where subscribe=1 and openid=?", WX_User.getMapp(), user_openid);
        if (null != user) {
            // 3天以内不算过期，直接返回用户；3天之后，需要更新用户信息
            if ((System.currentTimeMillis() - user.getExpires()) <= WX_Constants.DAY3) {
                return user;
            }
        }
        // 如果是订阅号则总为NULL,因为没有接口权限
        user = WeixinUtil.getUserInfo(getAccessTokenByopenId(wx_openid), user_openid);
        if (null != user) {
            user.setExpires(new Date().getTime());
            if (user.getSubscribe() == 1)// 关注的用户才更新，未关注的用户不更新
                commonDao
                        .updateOne(
                                "UPDATE wx_user T SET T.nickname = :nickname,T.sex = :sex,T.city = :city,T.country=:country,T.province=:province,T.headimgurl=:headimgurl,T.expires=:expires ,T.unionid=:unionid WHERE T.openid = :openid",
                                user);
        }
        return user;
    }

    public WX_User getWXUser(String user_openid) {
        WX_User user = commonDao.loadOne("SELECT * from wx_user where subscribe=1 and openid=?", WX_User.getMapp(), user_openid);
        if (null != user) {
            // 3天以内不算过期，直接返回用户；3天之后，需要更新用户信息
            if ((System.currentTimeMillis() - user.getExpires()) <= WX_Constants.DAY3) {
                return user;
            }
        }
        return null;
    }

    public WX_Reply queryReplySub(String wx_openid) {
        return commonDao.loadOne("SELECT * from wx_reply_sub where wx_openid=? ", WX_Reply.getMapp(), wx_openid);
    }

    public WX_Reply queryReplyKey(String wx_openid, String key) {
        System.out.println("======queryReplyKey====" + wx_openid + "====key: " + key);
        // 先进行全匹配查询
        WX_Reply rep = commonDao.loadOne("SELECT * from wx_reply_key where wx_openid=? and key_name=? ", WX_Reply.getMapp(), wx_openid, key);
        if (null != rep) {
            return rep;
        }
        // 再尝试进行模糊匹配
        rep = commonDao.loadOne("SELECT * from wx_reply_key where wx_openid=? and key_name like ? ", WX_Reply.getMapp(), wx_openid, "%" + key + "%");
        if (null != rep) {
            return rep;
        }
        // 再尝试无关键字匹配
        return commonDao.loadOne("SELECT * from wx_reply_nokey where wx_openid=? ", WX_Reply.getMapp(), wx_openid);
    }

    public String queryReplyMaterialText(WX_Reply reply) {
        return commonDao.getStringColumn("select content from wx_material_text where material_id=?", reply.getMaterial_id());
    }

    public List<Article> queryReplyMaterialArticel(WX_Reply reply) {
        return commonDao.loadList("select * from wx_material_article where material_id=? order by sort asc", Article.getMapp(), reply.getMaterial_id());
    }

    public Pager<SuperMessage> loadNewsByPage(String toUserName, Query query) {
        String page_sql = String.format("SELECT t.* FROM wx_msg t WHERE T.ToUserName =? %s", Query.getPageSQL("T", query));
        String count_sql = String.format("SELECT COUNT(*) FROM wx_msg T WHERE T.ToUserName = ? %s", Query.getCountSQL("T", query));
        List<SuperMessage> list = new ArrayList<SuperMessage>();
        try {
            System.out.println("page_sql::" + page_sql);
            list = commonDao.loadList(page_sql, SuperMessage.getFullNewsMapper(), toUserName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int total = commonDao.getCount(count_sql, toUserName);
        return new Pager<SuperMessage>(total, query.getPage(), list);
    }

    public Pager<SuperMessage> loadNewsByPage3(String toUserName, Query query, Integer dateType) throws Exception {
        String page_sql = "";
        String count_sql = "";
        Long[] t = {0l, 0l};
        List<SuperMessage> list = new ArrayList<SuperMessage>();
        int total = 0;
        switch (dateType) {
            //全部
            case 0:
                t = DateUtil.getDayTimestamp(new Date());
                page_sql = String.format("SELECT T.*,T1.nickname FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.ToUserName =? %s", Query.getPageSQL("T", query));
                count_sql = String.format("SELECT COUNT(*) FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.ToUserName = ? %s", Query.getCountSQL("T", query));
                list = commonDao.loadList(page_sql, SuperMessage.getFullNewsMapper(), toUserName);
                total = commonDao.getCount(count_sql, toUserName);
                break;
            //今天
            case 1:
                t = DateUtil.getDayTimestamp(new Date());
                page_sql = String.format("SELECT T.*,T1.nickname FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.CreateTime>?  and T.ToUserName =? %s", Query.getPageSQL("T", query));
                count_sql = String.format("SELECT COUNT(*) FROM wx_msg T,wx_user T1 WHERE T.CreateTime>?  and T.ToUserName = ? %s", Query.getCountSQL("T", query));
                list = commonDao.loadList(page_sql, SuperMessage.getFullNewsMapper(), t[0], toUserName);
                total = commonDao.getCount(count_sql, t[0], toUserName);
                break;
            //昨天
            case 2:
                t = DateUtil.getDayTimestamp(DateUtil.getYesterdayDate());
                page_sql = String.format("SELECT T.*,T1.nickname FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.CreateTime>? and T.CreateTime<? and T.ToUserName =? %s", Query.getPageSQL("T", query));
                count_sql = String.format("SELECT COUNT(*) FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.CreateTime>? and T.CreateTime<? and T.ToUserName = ? %s", Query.getCountSQL("T", query));
                list = commonDao.loadList(page_sql, SuperMessage.getFullNewsMapper(), t[0], t[1], toUserName);
                total = commonDao.getCount(count_sql, t[0], t[1], toUserName);
                break;
            //昨天之间
            case 3:
                t = DateUtil.getDayTimestamp(DateUtil.getYesterdayDate());
                page_sql = String.format("SELECT T.*,T1.nickname FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.CreateTime<? and T.ToUserName =? %s", Query.getPageSQL("T", query));
                count_sql = String.format("SELECT COUNT(*) FROM wx_msg T,wx_user T1 WHERE T.FromUserName = T1.openid and T.CreateTime<? and T.ToUserName = ? %s", Query.getCountSQL("T", query));
                list = commonDao.loadList(page_sql, SuperMessage.getFullNewsMapper(), t[0], toUserName);
                total = commonDao.getCount(count_sql, t[0], toUserName);
                break;
            default:
                return null;
        }

        return new Pager<SuperMessage>(total, query.getPage(), list);
    }

}
